package com.test.chatrobot3.service;

import com.test.chatrobot3.entity.DeepSeekRequest;
import com.test.chatrobot3.entity.DeepSeekResponse;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

import java.util.Collections;

@Service
@Slf4j
public class DeepSeekService {

    private static final String DEEPSEEK_API_URL = "https://api.deepseek.com/v1/chat/completions";
    private static final String API_KEY = "sk-0f5ac4a1f659440f90922421fc53ac87";
    private static final String MODEL_NAME = "deepseek-chat";
    private static final double DEFAULT_TEMPERATURE = 0.7;

    private static final Logger logger = LoggerFactory.getLogger(DeepSeekService.class);

    @Autowired
    private  RestTemplate restTemplate;

    public DeepSeekService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public String getAnswerFromDeepSeek(String question) {

        System.out.println(question);
        DeepSeekRequest request = buildStandardRequest(question);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("Authorization", "Bearer " + API_KEY);
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        return executeWithRetry(new HttpEntity<>(request, headers));
    }

    private DeepSeekRequest buildStandardRequest(String userInput) {
        return DeepSeekRequest.builder()
                .model(MODEL_NAME)
                .temperature(DEFAULT_TEMPERATURE)
                .messages(Collections.singletonList(
                        DeepSeekRequest.Message.builder()
                                .role("user")
                                .content(userInput)
                                .build()
                ))
                .build();
    }

    private String executeWithRetry(HttpEntity<DeepSeekRequest> entity) {
        int maxRetries = 3;
        int retryCount = 0;
        long retryInterval = 1000; // 1秒
        while (retryCount <= maxRetries) {
            try {
                ResponseEntity<DeepSeekResponse> response = restTemplate.exchange(
                        DEEPSEEK_API_URL,
                        HttpMethod.POST,
                        entity,
                        DeepSeekResponse.class
                );
                if (response.getStatusCode().is2xxSuccessful() &&
                        !response.getBody().getChoices().isEmpty()) {
                    System.out.println(response.getBody().getChoices().get(0).getMessage().getContent());
                    return response.getBody().getChoices().get(0).getMessage().getContent();
                }
                log.error("API请求失败，状态码：{}，响应体：{}",
                        response.getStatusCodeValue(),
                        response.getBody());
            } catch (HttpClientErrorException e) {
                handleHttpError(e);
                if (e.getStatusCode() == HttpStatus.TOO_MANY_REQUESTS) {
                    waitForRetry(retryInterval);
                    retryInterval *= 2; // 指数退避
                    continue;
                }
            } catch (Exception e) {
                log.error("API调用异常：{}", e.getMessage());
            }

            if (++retryCount > maxRetries) break;
            waitForRetry(retryInterval);
        }

        throw new RuntimeException("API调用失败，已达最大重试次数");
    }

    private void handleHttpError(HttpClientErrorException e) {
        log.error("API错误响应：{}", e.getResponseBodyAsString());
        if (e.getStatusCode() == HttpStatus.UNAUTHORIZED) {
            throw new RuntimeException("API密钥无效或过期");
        }
    }

    private void waitForRetry(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}